package sk.tramtatiri.pages.users;

//import java.nio.file.LinkOption;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import ofc4j.model.Chart;
import ofc4j.model.axis.Label.Rotation;
import ofc4j.model.axis.XAxis;
import ofc4j.model.axis.XAxisLabels;
import ofc4j.model.axis.YAxis;
import ofc4j.model.elements.AreaHollowChart;
import ofc4j.model.elements.BarChart;
import ofc4j.model.elements.BarChart.Style;

import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;

import sk.tramtatiri.MySession;
import sk.tramtatiri.OpenFlashChart;
import sk.tramtatiri.data.dao.interfaces.UserDao;
import sk.tramtatiri.data.dao.interfaces.UserInfoDao;
import sk.tramtatiri.data.dataobjects.UserInfo;

public class WeightWaistTrackerPanel extends Panel {

	private static final long serialVersionUID = -7869976227761441493L;

	@SpringBean
	private UserDao userDao;

	@SpringBean
	private UserInfoDao userInfoDao;

	private TextField<Integer> waist;
	private TextField<Integer> weight;
	private FeedbackPanel feedback;

	private org.apache.wicket.markup.html.basic.Label todayLabel;

	private String todayText;
	private String bmiTodayValue;
	private String bmiRegistrationValue;
	private org.apache.wicket.markup.html.basic.Label bmiTodayLabel;
	private org.apache.wicket.markup.html.basic.Label bmiRegistrationLabel;

	private List<UserInfo> lastUInfo0;

//	private User loggedUser;
	
	private Model model;
	private int days = 7;
	
	public WeightWaistTrackerPanel(String id) {
		super(id);
		
//		loggedUser = userDao.load(((MySession)getSession()).getUserID());
		
		weight = new TextField<Integer>("weight_input", new Model(""),Integer.class);
		waist = new TextField<Integer>("waist_input", new Model(""),Integer.class);

		todayLabel = new org.apache.wicket.markup.html.basic.Label("today",
				new PropertyModel(this, "todayText"));
		todayLabel.setOutputMarkupId(true);

		bmiTodayLabel = new org.apache.wicket.markup.html.basic.Label("bmiToday",
				new PropertyModel(this, "bmiTodayValue"));
		bmiTodayLabel.setOutputMarkupId(true);
		
		bmiRegistrationLabel = new org.apache.wicket.markup.html.basic.Label("bmiRegistration",
				new PropertyModel(this, "bmiRegistrationValue"));
		bmiRegistrationLabel.setOutputMarkupId(true);

		calculateRegistrationBMI();
		calculateBMI();

		Date today = new Date();
		String pattern0 = "dd. MM. yyyy";
		SimpleDateFormat formatter = new SimpleDateFormat(pattern0);

		todayText = formatter.format(today);

		feedback = new FeedbackPanel("feedback");
		feedback.setOutputMarkupId(true);

		drawCharts(getDays());

		Form wwTrackerForm = new Form("wwTrackerForm") {
			@Override
			protected void onSubmit() {
				if (waist.getInput() != "" || weight.getInput() != "") {

					Calendar cal = Calendar.getInstance();
					cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
							cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);

					Date date = new Date(cal.getTimeInMillis());

					UserInfo uinfo0 = userInfoDao.findByUserAndDate(
							((MySession) getSession()).getUserID(), date);

					if (uinfo0!=null) {
						UserInfo uinfoTmp = uinfo0;
						UserInfo temp = uinfoTmp;
						if (waist.getInput() == "" && weight.getInput() != "") {
							uinfoTmp.setWeight(Integer.parseInt(weight
									.getInput()));
						} else if (waist.getInput() != ""
								&& weight.getInput() == "") {
							uinfoTmp.setWaist(Integer.parseInt(waist.getInput()));
						} else if (waist.getInput() != ""
								&& weight.getInput() != "") {
							uinfoTmp.setWeight(Integer.parseInt(weight
									.getInput()));
							uinfoTmp.setWaist(Integer.parseInt(waist.getInput()));
						}
						userDao.load(((MySession) getSession()).getUserID())
								.getUserInfos().remove(temp);
						userDao.load(((MySession) getSession()).getUserID())
								.getUserInfos().add(uinfoTmp);
					} else {
						lastUInfo0 = userInfoDao
								.selectNewest(((MySession) getSession())
										.getUserID());
						UserInfo ui0 = null;
						if (!lastUInfo0.isEmpty()) {
							ui0 = lastUInfo0.get(0);
						}
						UserInfo uinfo1 = new UserInfo();
						uinfo1.setDate(new Date(cal.getTimeInMillis()));
						uinfo1.setUser(userDao.load(((MySession) getSession())
								.getUserID()));
						uinfo1.setUser_id(((MySession) getSession())
								.getUserID());
						if (waist.getInput() == "" && weight.getInput() != "") {
							uinfo1.setWeight(Integer.parseInt(weight.getInput()));
							uinfo1.setWaist(ui0.getWaist());
						} else if (waist.getInput() != ""
								&& weight.getInput() == "") {
							uinfo1.setWaist(Integer.parseInt(waist.getInput()));
							uinfo1.setWeight(ui0.getWeight());
						} else if (waist.getInput() != ""
								&& weight.getInput() != "") {
							uinfo1.setWeight(Integer.parseInt(weight.getInput()));
							uinfo1.setWaist(Integer.parseInt(waist.getInput()));
						}
						userInfoDao.save(uinfo1);
						userDao.load(((MySession) getSession()).getUserID())
								.getUserInfos().add(uinfo1);
					}

					calculateBMI();
					calculateRegistrationBMI();
					drawCharts(getDays());
				} else {
					feedback.error("Zadaj vahu alebo obvod pasa.");
				}

			}

		};

		wwTrackerForm.add(weight);
		wwTrackerForm.add(waist);
		wwTrackerForm.add(todayLabel);
		add(bmiTodayLabel);
		add(bmiRegistrationLabel);

		add(feedback);

		add(wwTrackerForm);
		
		model = new Model("poslednych 7 dni");
		String[] selectOptions = new String[] {"poslednych 7 dni", "poslednych 30 dni", "od datumu registracie"};
		DropDownChoice ddc = new DropDownChoice("dateIntervalChoice", model, Arrays.asList(selectOptions));
		Form<?> datePeriodForm = new Form<Void>("datePeriodForm") {
			@Override
			protected void onSubmit() {
				String str = (String) model.getObject();
				if(str.trim().equals("poslednych 7 dni")){
					setDays(7);
				} else if(str.trim().equals("poslednych 30 dni")) {
					setDays(30);
				} else {
					setDays(100);
				}
				drawCharts(getDays());
			}
		};
		datePeriodForm.add(ddc);
		add(datePeriodForm);
	}

	private void drawCharts(int days) {
		List<UserInfo> userInfoList = userInfoDao.selectLastXDays(((MySession) getSession()).getUserID(), days - 1);
		List<Number> weights = new ArrayList<Number>();
		List<Number> waists = new ArrayList<Number>();
		String[] dates = new String[userInfoList.size()];
		int i = 0;
		int minWeight = 1000;
		int maxWeight = 0;
		int minWaist = 1000;
		int maxWaist = 0;
		for (UserInfo ui : userInfoList) {
			weights.add(ui.getWeight());
			waists.add(ui.getWaist());

			SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
			dates[i] = sdf.format(ui.getDate());

			if (ui.getWeight() <= minWeight)
				minWeight = ui.getWeight();
			if (ui.getWeight() >= maxWeight)
				maxWeight = ui.getWeight();
			if (ui.getWaist() <= minWaist)
				minWaist = ui.getWaist();
			if (ui.getWaist() >= maxWaist)
				maxWaist = ui.getWaist();
			i++;
		}

		Chart chart1;
		Chart chart2;
		OpenFlashChart openFlsChart1 = null;
		OpenFlashChart openFlsChart2 = null;
		
		YAxis yaxis = new YAxis();
		yaxis.setSteps(5);
		XAxis xaxis = new XAxis();
		XAxisLabels xaxisLab = new XAxisLabels();
		xaxisLab.setRotation(Rotation.VERTICAL);
		xaxisLab.addLabels(dates);
		xaxis.setXAxisLabels(xaxisLab);
		
		if (days >= 8) {
			AreaHollowChart hollow1 = new AreaHollowChart();
			hollow1.addValues(weights);
			hollow1.setColour("#007FFF");
			hollow1.setTooltip("Vaha:#val#");
			hollow1.setText("Vaha");
			hollow1.setAlpha(0.1f);
			hollow1.setFontSize(15);
			hollow1.setDotSize(2);
			hollow1.setHaloSize(1);

			AreaHollowChart hollow2 = new AreaHollowChart();
			hollow2.addValues(waists);
			hollow2.setColour("##802A2A");
			hollow2.setTooltip("Obvod pasa:#val#");
			hollow2.setText("Obvod pasa");
			hollow2.setAlpha(0.1f);
			hollow2.setFontSize(15);
			hollow2.setDotSize(2);
			hollow2.setHaloSize(1);

			chart1 = new Chart();
			chart1.addElements(hollow1);
			chart1.setBackgroundColour("#FFFFFF");
			yaxis.setMin(minWeight - 10);
			yaxis.setMax(maxWeight + 10);
			chart1.setYAxis(yaxis);
			chart1.setXAxis(xaxis);

			openFlsChart1 = new OpenFlashChart("chart1", 300,
					400, chart1);

			chart2 = new Chart();
			chart2.addElements(hollow2);
			chart2.setBackgroundColour("#FFFFFF");
			yaxis.setMin(minWaist - 10);
			yaxis.setMax(maxWaist + 10);
			chart2.setYAxis(yaxis);
			chart2.setXAxis(xaxis);
			
			openFlsChart2 = new OpenFlashChart("chart2", 300, 400,
					chart2);
		} else {
			BarChart bar1 = new BarChart(Style.GLASS);
			bar1.addValues(weights);
			bar1.setColour("#1494A3");
			bar1.setTooltip("Vaha:#val#");
			bar1.setText("Vaha");
			bar1.setAlpha(0.1f);
			bar1.setFontSize(15);
			
			BarChart bar2 = new BarChart(Style.GLASS);
			bar2.addValues(waists);
			bar2.setColour("#1494A3");
			bar2.setTooltip("Obvod pasa:#val#");
			bar2.setText("Obvod pasa");
			bar2.setAlpha(0.1f);
			bar2.setFontSize(15);
			
			chart1 = new Chart();
			chart1.addElements(bar1);
			chart1.setBackgroundColour("#FFFFFF");
			yaxis.setMax(maxWeight + 10);
			chart1.setYAxis(yaxis);
			chart1.setXAxis(xaxis);

			openFlsChart1 = new OpenFlashChart("chart1", 300,
					400, chart1);

			chart2 = new Chart();
			chart2.addElements(bar2);
			chart2.setBackgroundColour("#FFFFFF");
			yaxis.setMax(maxWaist + 10);
			chart2.setYAxis(yaxis);
			chart2.setXAxis(xaxis);
			
			openFlsChart2 = new OpenFlashChart("chart2", 300, 400,
					chart2);
		}
		
		if (!userInfoList.isEmpty()) {
			openFlsChart1.setVisible(true);
			openFlsChart2.setVisible(true);
		} else {
			openFlsChart1.setVisible(false);
			openFlsChart2.setVisible(false);
		}
		
		boolean bool = true;

		try {
			remove(openFlsChart1);
			remove(openFlsChart2);
			bool = false;
		} catch (Exception e) {
			bool = false;
		}

		if (!bool) {
			add(openFlsChart1);
			add(openFlsChart2);
		}
	}

	/**
	 * @return the todayText
	 */
	public String getTodayText() {
		return todayText;
	}

	/**
	 * @param todayText
	 *            the todayText to set
	 */
	public void setTodayText(String todayText) {
		this.todayText = todayText;
	}

	/**
	 * @return the bmiValue
	 */
	public String getBmiTodayValue() {
		return bmiTodayValue;
	}

	/**
	 * @param bmiValue
	 *            the bmiValue to set
	 */
	public void setBmiTodayValue(String bmiValue) {
		this.bmiTodayValue = bmiValue;
	}

	private void calculateRegistrationBMI() {
		List<UserInfo> firstUInfo = userInfoDao.selectFirst(((MySession)getSession()).getUserID());
		
		int height = (userDao.load(((MySession)getSession()).getUserID())
				.getHeight());
		int weight = firstUInfo.get(0).getWeight();

		double heightValueInM = height / 100.0;
		double bmi = weight / Math.pow(heightValueInM, 2);

		int pom = (int) (bmi * 100);

		setBmiRegistrationValue(Double.toString(pom / 100.0));
	}
	
	private void calculateBMI() {
		lastUInfo0 = userInfoDao.selectNewest(((MySession) getSession())
				.getUserID());
		int curr_height = (userDao.load(((MySession)getSession()).getUserID())
				.getHeight());
		int curr_weight = lastUInfo0.get(0).getWeight();

		double heightValueInM = curr_height / 100.0;
		double bmi = curr_weight / Math.pow(heightValueInM, 2);

		int pom = (int) (bmi * 100);

		setBmiTodayValue(Double.toString(pom / 100.0));
	}

	public int getDays() {
		return days;
	}

	public void setDays(int days) {
		this.days = days;
	}

	public String getBmiRegistrationValue() {
		return bmiRegistrationValue;
	}

	public void setBmiRegistrationValue(String bmiRegistrationValue) {
		this.bmiRegistrationValue = bmiRegistrationValue;
	}

}
